package com.jiangy.oauth2login.config;

import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;

import java.io.PrintWriter;

/**
 * <p>创建时间: 2024/8/12 </p>
 *
 * @author <a href="mailto:jiangliu0316@outlook.com" rel="nofollow">蒋勇</a>
 */
@Configuration
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {

    //    final OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
//    final OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService;
    final MyAuthenticationEntryPoint authenticationEntryPoint;
    final OAuth2LoginAuthenticationSuccessHandler successHandler;
    final OAuth2LoginUserHandler userHandler;

    public OAuth2LoginSecurityConfig(MyAuthenticationEntryPoint authenticationEntryPoint, OAuth2LoginAuthenticationSuccessHandler successHandler, OAuth2LoginUserHandler userHandler) {
//        this.oidcUserService = oidcUserService;
//        this.oAuth2UserService = oAuth2UserService;
        this.authenticationEntryPoint = authenticationEntryPoint;
        this.successHandler = successHandler;
        this.userHandler = userHandler;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/error", "/logout", "/login").permitAll()
                        .anyRequest().authenticated()
                )
                .exceptionHandling(handler -> handler
                        .authenticationEntryPoint(authenticationEntryPoint)
                )
                .sessionManagement(Customizer.withDefaults())
                .oauth2Login(login -> {
                    successHandler.setOauth2UserHandler(userHandler);
                    login.successHandler(successHandler);
                    // 配置后再获取用户信息的时候就回调用配置的用户服务，此处可以作为扩展点，让外部社交用户信息与系统内用户信息关联
//                            .userInfoEndpoint(userInfo -> userInfo
//                                    .oidcUserService(oidcUserService)
//                                    .userService(oAuth2UserService)
//                            );
                })
                .logout(
                        // 仅本地客户端退出场景 https://docs.spring.io/spring-security/reference/servlet/authentication/logout.html
                        logout -> logout.logoutSuccessHandler((request, response, authentication) -> {
                            // 设置响应内容类型
                            response.setContentType("application/json");
                            response.setCharacterEncoding("UTF-8");

                            // 设置响应状态码为200
                            response.setStatus(HttpServletResponse.SC_OK);

                            // 发送JSON响应
                            PrintWriter out = response.getWriter();
                            out.print("\"message\":\"Logout Success\"}");
                            out.flush();
                        })
                );
        return http.build();
    }
}